package com.android.jay.lib_video.videoplayer.core;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.SurfaceTexture;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import android.media.MediaPlayer;

import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RelativeLayout;

import com.android.jay.lib_video.R;

import java.io.IOException;

import androidx.annotation.NonNull;

/**
 * Created by wzp on 2020/2/5 0005.
 * <p>
 * 描述  ：todo
 */
public class CustomVideoView extends RelativeLayout implements
        MediaPlayer.OnPreparedListener, MediaPlayer.OnCompletionListener,
        MediaPlayer.OnErrorListener, View.OnClickListener, TextureView.SurfaceTextureListener, MediaPlayer.OnSeekCompleteListener {


    /**
     * 播放器状态
     **/

    private static final int STATE_ERROR = -1;
    private static final int STATE_IDLE = 0;
    private static final int STATE_PLAYING = 1;
    private static final int STATE_PAUSING = 2;
    private static final int STATE_TOTAL_COUNT = 3;

    /**
     * UI
     **/
    private RelativeLayout mPlayerView;
    private TextureView mVideoView;
    private Button mMiniPlayBtn;
    private ImageView mFullBtn;
    private ImageView mLoadingBar;
    private AudioManager audioManager;
    private Surface videoSurface;


    /**
     * data
     **/
    //视频的url
    private String mUrl;
    //是否静音
    private boolean isMute;
    //高度是通过16:9 计算出来的
    private int mScreenWidth, mScreenHeight;


    /**
     * state
     **/
    private boolean canPlay = true;
    //两种是真暂停 1. 用户点击 2. 视频播放完毕
    private boolean mIsRealPause;
    private boolean mIsComplete;
    private int mCurrentCount;
    private int playerState = STATE_IDLE;


    private MediaPlayer mediaPlayer;
    private ADVideoPlayerListener listener;
    private ScreenEventReceiver mScreenReceiver;

    public CustomVideoView(Context context) {
        this(context, null);
        audioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
        initData();
        initView();
        registerBroadcastReceiver();

    }

    private void registerBroadcastReceiver() {
        if (mScreenReceiver == null) {
            mScreenReceiver = new ScreenEventReceiver();
            IntentFilter filter = new IntentFilter();
            filter.addAction(Intent.ACTION_SCREEN_OFF);
            filter.addAction(Intent.ACTION_USER_PRESENT);
            getContext().registerReceiver(mScreenReceiver, filter);
        }
    }

    private void unRegisterBroadcastReceiver() {
        if (mScreenReceiver != null) {
            getContext().unregisterReceiver(mScreenReceiver);
        }
    }


    private void initView() {
        LayoutInflater inflater = LayoutInflater.from(getContext());
        mPlayerView = (RelativeLayout) inflater.inflate(R.layout.video_player_layout, this);
        mVideoView = mPlayerView.findViewById(R.id.xadsdk_player_video_textureView);
        mVideoView.setOnClickListener(this);
        mVideoView.setKeepScreenOn(true);
        mVideoView.setSurfaceTextureListener(this);
        initSmallLayout();
    }

    private void initSmallLayout() {
        LayoutParams params = new LayoutParams(mScreenWidth, mScreenHeight);
        params.addRule(RelativeLayout.CENTER_IN_PARENT);
        mPlayerView.setLayoutParams(params);

        mMiniPlayBtn = mPlayerView.findViewById(R.id.xadsdk_small_play_btn);
        mFullBtn = mPlayerView.findViewById(R.id.xadsdk_to_full_view);
        mLoadingBar = mPlayerView.findViewById(R.id.loading_bar);
        mMiniPlayBtn.setOnClickListener(this);
        mFullBtn.setOnClickListener(this);
    }

    private void initData() {
        DisplayMetrics dm = new DisplayMetrics();
        WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
        wm.getDefaultDisplay().getMetrics(dm);
        mScreenWidth = dm.widthPixels;
        mScreenHeight = (int) (mScreenWidth * (9 / 16.0f));
    }

    public CustomVideoView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CustomVideoView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);


    }

    private void checkMediaPlayer() {
        if (mediaPlayer == null) {
            mediaPlayer = new MediaPlayer();
            mediaPlayer.setOnPreparedListener(this);
            mediaPlayer.setOnCompletionListener(this);
            mediaPlayer.setOnErrorListener(this);
            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        }
    }

    /**
     * 播放状态 显示View
     **/
    private void showPlayorPauseView(boolean show) {
        mFullBtn.setVisibility(show ? VISIBLE : GONE);
        mMiniPlayBtn.setVisibility(show ? GONE : VISIBLE);
        mLoadingBar.clearAnimation();
        mLoadingBar.setVisibility(GONE);
    }

    private void showLoadingView() {
        mFullBtn.setVisibility(GONE);
        mLoadingBar.setVisibility(VISIBLE);
        AnimationDrawable anim = (AnimationDrawable) mLoadingBar.getBackground();
        anim.start();
        mMiniPlayBtn.setVisibility(GONE);
    }

    private void showPlayView() {
        mLoadingBar.clearAnimation();
        mLoadingBar.setVisibility(View.GONE);
        mMiniPlayBtn.setVisibility(View.GONE);
    }

    /**
     * 进入播放状态后的更新
     **/

    private void entryResumeState() {
        setCurrentPlayState(STATE_PLAYING);
        setmIsComplete(false);
        setmIsRealPause(false);
    }

    private void setCurrentPlayState(int statePlaying) {
        playerState = statePlaying;
    }

    public boolean ismIsRealPause() {
        return mIsRealPause;
    }

    public void setmIsRealPause(boolean mIsRealPause) {
        this.mIsRealPause = mIsRealPause;
    }

    public boolean ismIsComplete() {
        return mIsComplete;
    }

    public void setmIsComplete(boolean mIsComplete) {
        this.mIsComplete = mIsComplete;
    }

    public void isShowFullBtn(boolean isShow) {
        mFullBtn.setImageResource(isShow ? R.drawable.xadsdk_ad_mini : R.drawable.xadsdk_ad_mini_null);
        mFullBtn.setVisibility(isShow ? View.VISIBLE : View.GONE);
    }

    /**
     * true is no voice
     **/

    public void mute(boolean mute) {
        isMute = mute;
        if (mediaPlayer != null && this.audioManager != null) {
            float volume = isMute ? 0.0f : 1.0f;
            mediaPlayer.setVolume(volume, volume);
        }
    }


    public boolean isPlaying() {
        if (mediaPlayer != null && mediaPlayer.isPlaying()) {
            return true;
        }
        return false;
    }


    @Override
    protected void onVisibilityChanged(@NonNull View changedView, int visibility) {
        if (visibility == VISIBLE) {
            if (ismIsRealPause() || ismIsComplete()) {
                // 主动暂停
                pause();
            } else {
                start();
            }
        } else {
            // 不可见处理
            pause();
        }
    }

    @Override
    public void onPrepared(MediaPlayer mp) {
        //加载成功
        showPlayView();
        if (mediaPlayer != null) {
            mCurrentCount = 0;
            setCurrentPlayState(STATE_PLAYING);
            start();
            if (listener != null) listener.onAdVideoLoadSuccess();
        }
    }

    @Override
    public void onCompletion(MediaPlayer mp) {
        //播放完毕
        playBack();
        setmIsComplete(true);
        setmIsRealPause(true);
        if (listener != null) listener.onAdVideoLoadComplete();
    }

    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {
        setCurrentPlayState(STATE_ERROR);
        if (mCurrentCount >= STATE_TOTAL_COUNT) {
            showPlayorPauseView(false);
            if (listener != null) listener.onAdVideoLoadFailed();
        }
        stop();
        return false;
    }


    @Override
    public void onClick(View v) {
        if (v == mMiniPlayBtn) {
            if (playerState == STATE_PAUSING) {
                start();
            } else {
                load();
            }
        } else if (v == mFullBtn) {
            if (listener != null) {
                listener.onClickFullScreenBtn();
            }
        } else if (v == mVideoView) {
            if (listener != null) {
                listener.onClickVideo();
            }
        }
    }


    /**
     * surface
     **/

    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
        //surface可用
        videoSurface = new Surface(surface);
        checkMediaPlayer();
        mediaPlayer.setSurface(videoSurface);
        load();
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {

    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
        return false;
    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surface) {

    }


    public void setDataSource(String mUrl) {
        this.mUrl = mUrl;
    }

    /**
     * 完成视频加载
     **/

    public void load() {
        if (this.playerState != STATE_IDLE) {
            return;
        }
        try {
            showLoadingView();
            setCurrentPlayState(STATE_IDLE);
            checkMediaPlayer();
            mute(true);
            mediaPlayer.setDataSource(this.mUrl);
            mediaPlayer.prepareAsync();
        } catch (IOException e) {
            stop();
        }
    }

    private void stop() {
        if (this.mediaPlayer != null) {
            this.mediaPlayer.reset();
            this.mediaPlayer.setOnSeekCompleteListener(null);
            this.mediaPlayer.stop();
            this.mediaPlayer.release();
            this.mediaPlayer = null;
        }
        setCurrentPlayState(STATE_IDLE);
        if (mCurrentCount < STATE_TOTAL_COUNT) {
            mCurrentCount += 1;
            load();
        } else {
            showPlayorPauseView(false);
        }
    }

    public void destroy() {
        if (this.mediaPlayer != null) {
            this.mediaPlayer.setOnSeekCompleteListener(null);
            this.mediaPlayer.stop();
            this.mediaPlayer.release();
            this.mediaPlayer = null;
        }
        setCurrentPlayState(STATE_IDLE);
        mCurrentCount = 0;
        setmIsRealPause(false);
        setmIsComplete(false);
        unRegisterBroadcastReceiver();
        showPlayorPauseView(false);
    }

    /**
     * 播放视频
     **/
    public void start() {
        if (this.playerState != STATE_PLAYING) {
            return;
        }
        if (!isPlaying()) {
            entryResumeState();
            mediaPlayer.setOnSeekCompleteListener(this);
            mediaPlayer.start();
            showPlayorPauseView(true);
        } else {
            showPlayorPauseView(false);
        }
    }


    /**
     * 跳到指定播放视屏   小屏播放跳到全屏会调用这个方法
     */

    public void seekAndResume(int postion) {
        if (mediaPlayer != null) {
            showPlayorPauseView(true);
            entryResumeState();
            mediaPlayer.seekTo(postion);
            mediaPlayer.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
                @Override
                public void onSeekComplete(MediaPlayer mp) {
                    mediaPlayer.start();
                }
            });
        }
    }


    public void seekAndPause(int postion) {
        if (mediaPlayer != null) {
            if (this.playerState != STATE_PLAYING) {
                return;
            }
            showPlayorPauseView(false);
            setCurrentPlayState(STATE_PAUSING);
            if (isPlaying()) {
                mediaPlayer.seekTo(postion);
                mediaPlayer.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
                    @Override
                    public void onSeekComplete(MediaPlayer mp) {
                        mediaPlayer.pause();
                    }
                });
            }
        }
    }

    /**
     * 播放完成回到初始状态
     **/

    public void playBack() {
        setCurrentPlayState(STATE_PAUSING);
        if (mediaPlayer != null) {
            mediaPlayer.setOnSeekCompleteListener(null);
            mediaPlayer.seekTo(0);
            mediaPlayer.pause();
        }
        this.showPlayorPauseView(false);
    }


    public void pause() {
        if (this.playerState != STATE_PAUSING) {
            return;
        }
        setCurrentPlayState(STATE_PAUSING);
        if (isPlaying()) {
            mediaPlayer.pause();
        }
        this.showPlayorPauseView(false);
    }


    @Override
    public void onSeekComplete(MediaPlayer mp) {

    }


    public void setListener(ADVideoPlayerListener listener) {
        this.listener = listener;
    }

    //全屏不显示暂停状态,后续可以整合，不必单独出一个方法
    public void pauseForFullScreen() {
        if (playerState != STATE_PLAYING) {
            return;
        }
        setCurrentPlayState(STATE_PAUSING);
        if (isPlaying()) {
            mediaPlayer.pause();
            if (!this.canPlay) {
                mediaPlayer.seekTo(0);
            }
        }
    }


    public int getCurrentPosition() {
        if (this.mediaPlayer != null) {
            return mediaPlayer.getCurrentPosition();
        }
        return 0;
    }

    /**
     * 供slot层来实现具体点击逻辑,具体逻辑还会变，
     * 如果对UI的点击没有具体监测的话可以不回调
     */
    public interface ADVideoPlayerListener {
        void onBufferUpdate(int time);

        void onClickFullScreenBtn();

        void onClickVideo();

        void onClickBackBtn();

        void onClickPlay();

        void onAdVideoLoadSuccess();

        void onAdVideoLoadFailed();

        void onAdVideoLoadComplete();
    }

    private class ScreenEventReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction() == null) {
                return;
            }
            switch (intent.getAction()) {
                case Intent.ACTION_USER_PRESENT:
                    //亮屏事件处理
                    if (ismIsRealPause()) {
                        pause();
                    } else {
                        start();
                    }
                    break;
                case Intent.ACTION_SCREEN_OFF:
                    if (playerState == STATE_PLAYING) {
                        pause();
                    }
                    break;
            }

        }
    }
}
